package com.distribute.framework.core.apt;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BaseIO {

	static Map<String,String> fileContents = new HashMap();
	public String findEx(String filename, String flag) {
		String str=fileContents.get(filename);
		if(str==null){
			str = readFile(filename,"UTF-8");
			fileContents.clear();
			fileContents.put(filename, str);
		}
		int indexOf = -1;
		if((indexOf=str.indexOf(flag))==-1){
			return null;			
		}
		str = str.substring(indexOf);
		str = str.substring(str.indexOf("\n")+1);
		str = str.substring(0,str.indexOf(flag));
		if(str.lastIndexOf("\n")==-1)return null;
		str = str.substring(0, str.lastIndexOf("\n"));
		return str;
	}
	
	public String find(String filename, String regex, int group) {
		String contentString=readFile(filename,getCharset((filename)));
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(contentString);
		if(matcher.find())
			return matcher.group(group);
		return null;
	}

	public int indexOf(String filename, String string) {
		return readFile(filename,getCharset((filename))).indexOf(string);
	}

	public String readFile(String filename, String encode) {
		String fileString="";
		try{
			if(!new File(filename).exists())
				return "";
			InputStream input = new FileInputStream(filename);
			BufferedReader reader=new BufferedReader(new InputStreamReader(input,encode));		
			String strLine=null;
			while((strLine=reader.readLine())!=null)
				fileString+=strLine+"\n";
		}catch(Exception ex){
			throw new RuntimeException(ex);
		}
   		return fileString;
	}

	public void writeFile(String filename, String content, String encode) {
		try{
			filename=filename.replace("/", "\\");
			filename=filename.replace("\\\\", "\\");
			String filePath=filename.substring(0,filename.lastIndexOf("\\"));
			if(!new File(filePath).exists())
				new File(filePath).mkdirs();
			FileOutputStream fos = new FileOutputStream(filename);
			Writer out = new OutputStreamWriter(fos,encode);
			out.write(content);
			out.close();
		}catch(Exception ex){
			throw new RuntimeException(ex);
		}
	}

	public void append(String filename, String string) {
		String xmlString=file(filename);	
		xmlString+=string;
		writeFile(filename,xmlString,getCharset(filename));
	}

	public int find(String filename, String string) {
		String xmlString=file(filename);		
		return xmlString.indexOf(string);
	}

	public Boolean insert(String filename, String srcReg, String replace) {
		String xmlString=file(filename);		
		Pattern pattern = Pattern.compile(srcReg);
		Matcher matcher = pattern.matcher(xmlString);
		if(matcher.find()){
			xmlString=xmlString.replaceAll(srcReg,replace);
			writeFile(filename,xmlString,getCharset(filename));
			return true;
		}
		else
			return false;
	}
	
	public String file(String filename,String encode)
	{
		return readFile(filename,encode);
	}
	
	public String file(String filename)
	{
		return readFile(filename,getCharset((filename)));
	}
	
	private String getCharset(String filename) {
		try {
			if(!new File(filename).exists())
				return "UTF-8";
			return getCharset(new FileInputStream(filename));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return "UTF-8";
		}
	}

	/**
	 * 获取文件编码
	 * @param file
	 * @return
	 * ANSI：无格式定义；
	 * Unicode： 前两个字节为FFFE；
	 * Unicode big endian：前两字节为FEFF；　 
	 * UTF-8：前两字节为EFBB；
	 */
	public static String getCharset( InputStream is ) {   
        String charset = "GBK";   
        byte[] first3Bytes = new byte[3];   
        try {
            boolean checked=false;   
            BufferedInputStream bis = new BufferedInputStream(is);   
            bis.mark( 0 );   
            int read = bis.read( first3Bytes, 0, 3 );   
            if ( read == -1 ) return charset;   
            if ( first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE ) {   
                charset = "UTF-16LE";   
                checked = true;   
            }   
            else if ( first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF ) {   
                charset = "UTF-16BE";   
                checked = true;   
            }   
            else if ( first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF ) {   
                charset = "UTF-8";   
                checked = true;   
            }   
            bis.reset();   
            if ( !checked ) {   
                int loc = 0;
                while ( (read = bis.read()) != -1 ) {   
                    loc++;   
                    if ( read >= 0xF0 ) break;   
                    if ( 0x80 <= read && read <= 0xBF ) // 单独出现BF以下的，也算是GBK   
                    break;   
                    if ( 0xC0 <= read && read <= 0xDF ) {   
                        read = bis.read();   
                        if ( 0x80 <= read && read <= 0xBF ) // 双字节 (0xC0 - 0xDF) (0x80   
                                                                        // - 0xBF),也可能在GB编码内   
                        continue;   
                        else break;   
                    }   
                    else if ( 0xE0 <= read && read <= 0xEF ) {// 也有可能出错，但是几率较小   
                        read = bis.read();   
                        if ( 0x80 <= read && read <= 0xBF ) {   
                            read = bis.read();   
                            if ( 0x80 <= read && read <= 0xBF ) {   
                                charset = "UTF-8";   
                                break;   
                            }   
                            else break;   
                        }   
                        else break;   
                    }   
                }
                bis.close();
            }
        } catch ( Exception e ) {   
            e.printStackTrace();   
        }
        return charset;   
    }


}